package com.yunji.cabinet.business;

import com.google.common.collect.Lists;
import com.yunji.base.engine.generate.BaseDataCodeGenerate;
import com.yunji.cabinet.bo.SpecificUpgradeCabinetBO;
import com.yunji.cabinet.bo.UpgradeInfoListBO;
import com.yunji.cabinet.context.calculate.CabinetVersionCalculate;
import com.yunji.cabinet.domain.ContainerDO;
import com.yunji.cabinet.domain.UpgradeFileDO;
import com.yunji.cabinet.domain.UpgradeTaskDO;
import com.yunji.cabinet.dto.UpgradeTaskDTO;
import com.yunji.cabinet.engine.UpgradeTaskEngine;
import com.yunji.cabinet.enums.UpgradeTaskStatus;
import com.yunji.cabinet.enums.UpgradeTaskTypeEnum;
import com.yunji.cabinet.params.UpgradeTaskParam;
import com.yunji.cabinet.service.ICabinetService;
import com.yunji.cabinet.service.IUpgradeFileService;
import com.yunji.cabinet.service.IUpgradeInfoService;
import com.yunji.cabinet.service.IUpgradeTaskService;
import com.yunji.cabinet.vo.UpgradeInfoVO;
import com.yunji.cabinet.vo.UpgradeTaskVO;
import com.yunji.common.base.Triple;
import com.yunji.common.constant.PrefixConstant;
import com.yunji.common.enums.common.ErrorEnum;
import com.yunji.common.utils.StringUtils;
import com.yunji.common.utils.TimeUtils;
import com.yunji.common.utils.bean.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.List;

@Component
public class UpgradeTaskBusiness {

    @Resource
    private IUpgradeFileService upgradeFileService;

    @Resource
    private IUpgradeTaskService upgradeTaskService;

    @Resource
    private UpgradeTaskEngine upgradeTaskEngine;

    @Resource
    private IUpgradeInfoService upgradeInfoService;

    @Resource
    private ICabinetService cabinetService;

    private final String errorMessage = "{}货柜参数与文件不一致,机型-芯片类型,前者为:{}-{},后者为:{}-{}";
    private final String refuseMessage = "{}货柜版本与升级文件版本一致,无需重复升级";

    public void checkCabinetVersion(List<ContainerDO> list, UpgradeFileDO fileDO){
        String modelType = fileDO.getModelType();
        String chipType = fileDO.getChipType();
        String version = fileDO.getVersion();
        String message;
        for (ContainerDO cabinetDO : list) {
            Triple<String, String, String> triple = CabinetVersionCalculate.getTaskCheckParam(cabinetDO.getVersion());
            String cabinetModelType = triple.getFirst();
            String cabinetChipType = triple.getSecond();
            String cabinetVersion = triple.getThird();
            if (!modelType.equals(cabinetModelType) || !chipType.equals(cabinetChipType)) {
                message = StringUtils.format(errorMessage,cabinetDO.getContainerName()
                        ,cabinetModelType,cabinetChipType,modelType,chipType);
                throw new RuntimeException(message);
            }else {
                if (version.equals(cabinetVersion)){
                    throw new RuntimeException(StringUtils.format(refuseMessage,cabinetDO.getContainerName()));
                }
            }
        }
    }

    public String create(UpgradeTaskDTO dto) {
        Integer taskType = dto.getTaskType();
        SpecificUpgradeCabinetBO bo = new SpecificUpgradeCabinetBO();
        BeanUtils.clone(dto,bo);
        if (BeanUtils.isNotNull(dto.getContainerIds())) {
            if (UpgradeTaskTypeEnum.BATCH.getCode().equals(taskType)) {
                bo.setIgnoreContainerIds(dto.getContainerIds());
            } else {
                bo.setExistContainerIds(dto.getContainerIds());
            }
        }
        List<ContainerDO> list =  cabinetService.specificUpgradeCabinetList(bo);

        Long fileId = dto.getFileId();
        UpgradeFileDO fileDO = upgradeFileService.select(fileId);
        Assert.isTrue(BeanUtils.isNotNull(fileDO), ErrorEnum.BUSINESS_712005.getText());

        checkCabinetVersion(list,fileDO);

        // 没有货柜版本的 先去调硬件获取版本号
        // 获取所有满足条件的货柜chip码 放入升级
        UpgradeTaskDO upgradeTaskDO = new UpgradeTaskDO();
        BeanUtils.clone(dto,upgradeTaskDO);
        upgradeTaskDO.setStartTime(TimeUtils.getNowDate());
        upgradeTaskDO.setTaskCode(BaseDataCodeGenerate.generateSiteAuditCode(PrefixConstant.CABINET_UPGRADE_TASK));
        upgradeTaskDO.setFacilityNums(list.size());
        upgradeTaskDO.setVersion(fileDO.getVersion());
        upgradeTaskService.create(upgradeTaskDO);
        upgradeTaskEngine.createTask(upgradeTaskDO,list);

        return upgradeTaskDO.getTaskCode();
    }

    public List<UpgradeTaskVO> search(UpgradeTaskParam param) {
        return upgradeTaskService.searchVOList(param);
    }

    public UpgradeTaskVO select(String taskCode) {
        UpgradeTaskVO vo = upgradeTaskService.selectVO(taskCode);
        UpgradeInfoListBO bo = new UpgradeInfoListBO();
        bo.setTaskCode(taskCode);
        List<UpgradeInfoVO> voList = upgradeInfoService.searchVO(bo);
        vo.setInfoList(voList);
        vo.setWaitFacility(upgradeInfoService.countNumsByStatus(taskCode, UpgradeTaskStatus.TO_BE_START.getCode()));
        vo.setCancelFacility(upgradeInfoService.countNumsByStatus(taskCode, UpgradeTaskStatus.BE_CANCEL.getCode()));
        vo.setCompleteFacility(upgradeInfoService.countNumsByStatus(taskCode, UpgradeTaskStatus.BE_FINISHED.getCode()));
        return vo;
    }

    public boolean closeTask(String taskCode) {
        upgradeInfoService.closeTaskByTaskCode(taskCode);
        return upgradeTaskService.modifyStatus(taskCode,UpgradeTaskStatus.BE_CANCEL.getCode(), Lists.newArrayList(
                 UpgradeTaskStatus.TO_BE_START.getCode(),UpgradeTaskStatus.BE_READY.getCode(),UpgradeTaskStatus.IN_PROGRESS.getCode()
        ));
    }
}
